﻿using ERP.Common.Results;
using ERP.Team.ProductionSystem;
using ERP.ERPSystem.ProductionSystem.Dto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.ObjectMapping;
using Volo.Abp.Uow;

namespace ERP.ERPSystem.ProductionSystem
{
    public class CustomerOrderServices : ApplicationService, ICustomerOrderServices
    {
        private readonly IRepository<CustomerOrderModel, int> _customerOrderModelBrs;
        private readonly IRepository<ProductInfoRelationModel, int> _ProductInfoRelationModelBrs;
        private readonly IRepository<MaterialproductModel, int> _materialproductModelBrs;
        private readonly IRepository<MaterialRequirementModel, int> _materialRequirementRepository;

        public CustomerOrderServices(IRepository<CustomerOrderModel, int> customerOrderModelBrs, 
            IRepository<ProductInfoRelationModel, int> productInfoRelationModelBrs,
            IRepository<MaterialproductModel, int> materialproductModelBrs,
            IRepository<MaterialRequirementModel, int> materialRequirementRepository)
        {
            _customerOrderModelBrs = customerOrderModelBrs;
            _ProductInfoRelationModelBrs = productInfoRelationModelBrs;
            _materialproductModelBrs = materialproductModelBrs;
            _materialRequirementRepository = materialRequirementRepository;
        }
        /// <summary>
        /// 获取产品分类+分页
        /// </summary>
        /// <returns></returns>
        public async Task<APIPaging<ProductInfoRelationModel>> GetProductInfoRelation(string? code, string? Name,int page = 1, int limit = 10)
        {
            try
            {
                APIPaging<ProductInfoRelationModel> pageList = new APIPaging<ProductInfoRelationModel>();
                var roductInfoRelation = await _ProductInfoRelationModelBrs.GetQueryableAsync();
                roductInfoRelation = roductInfoRelation.WhereIf(!string.IsNullOrEmpty(code), m => m.ProductCode.Contains(code));
                roductInfoRelation = roductInfoRelation.WhereIf(!string.IsNullOrEmpty(Name), m => m.ProductName.Contains(Name));
                pageList.ListDate = roductInfoRelation.OrderByDescending(m => m.Id).Skip((page - 1) * limit).Take(limit).ToList();
                pageList.PageCount = roductInfoRelation.Count();
                pageList.PageIndex=Convert.ToInt32(Math.Ceiling(pageList.PageCount * 1.0 / limit));   
                return pageList;
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 添加客户订单
        /// </summary>
        /// <param name="customerOrderDto">客户订单信息</param>
        /// <returns>订单ID</returns>
        public async Task<int> AddCustomerOrder(CustomerOrderDto customerOrderDto)
        {
            try
            {
                // 验证必需字段
                if (string.IsNullOrEmpty(customerOrderDto.ProductCode))
                    throw new ArgumentException("产品编号不能为空");
                if (string.IsNullOrEmpty(customerOrderDto.ProductName))
                    throw new ArgumentException("产品名称不能为空");
                if (string.IsNullOrEmpty(customerOrderDto.OrderCode))
                    throw new ArgumentException("订单编码不能为空");
                if (string.IsNullOrEmpty(customerOrderDto.CustomerName))
                    throw new ArgumentException("客户名称不能为空");
                if (string.IsNullOrEmpty(customerOrderDto.Unit))
                    throw new ArgumentException("单位不能为空");

                // 创建客户订单实体
                var customerOrder = new CustomerOrderModel
                {
                    ProductCode = customerOrderDto.ProductCode ?? "",
                    ProductName = customerOrderDto.ProductName ?? "",
                    ProductSpec = customerOrderDto.ProductSpec ?? "",
                    OrderNumber = customerOrderDto.OrderCode ?? "",
                    CustomerCode = customerOrderDto.CustomerCode ?? "", // 添加客户编码
                    CustomerName = customerOrderDto.CustomerName ?? "",
                    OrderDate = customerOrderDto.OrderDate,
                    DeliveryDate = customerOrderDto.DeliveryDate,
                    OrderQuantity = customerOrderDto.OrderQuantity,
                    Unit = customerOrderDto.Unit ?? "",
                    SpecificationModel = customerOrderDto.SpecModel ?? "",
                    QualityRequirement = customerOrderDto.QualityRequirements ?? "",
                    OrderStatus = customerOrderDto.OrderStatus
                };

                // 插入到数据库并保存更改
                var result = await _customerOrderModelBrs.InsertAsync(customerOrder, autoSave: true);
                
                return result.Id;
            }
            catch (Exception ex)
            {
                // 重新抛出异常，保留原始错误信息
                throw new Exception($"添加客户订单失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 分页查询客户订单列表
        /// </summary>
        /// <param name="queryDto">查询条件</param>
        /// <returns>分页订单列表</returns>
        public async Task<APIPaging<CustomerOrderModel>> GetCustomerOrderList(CustomerOrderQueryDto queryDto)
        {
            try
            {
                var pageList = new APIPaging<CustomerOrderModel>();
                var query = await _customerOrderModelBrs.GetQueryableAsync();

                // 条件筛选
                query = query.WhereIf(!string.IsNullOrEmpty(queryDto.OrderCode), 
                    m => m.OrderNumber.Contains(queryDto.OrderCode));
                
                query = query.WhereIf(!string.IsNullOrEmpty(queryDto.CustomerName), 
                    m => m.CustomerName.Contains(queryDto.CustomerName));
                
                query = query.WhereIf(!string.IsNullOrEmpty(queryDto.ProductCode), 
                    m => m.ProductCode.Contains(queryDto.ProductCode));
                
                query = query.WhereIf(!string.IsNullOrEmpty(queryDto.ProductName), 
                    m => m.ProductName.Contains(queryDto.ProductName));
                
                query = query.WhereIf(queryDto.OrderStatus.HasValue, 
                    m => m.OrderStatus == queryDto.OrderStatus.Value);

                // 日期范围筛选
                if (queryDto.StartDate.HasValue)
                {
                    query = query.Where(m => m.OrderDate >= queryDto.StartDate.Value);
                }
                
                if (queryDto.EndDate.HasValue)
                {
                    var endDate = queryDto.EndDate.Value.Date.AddDays(1);
                    query = query.Where(m => m.OrderDate < endDate);
                }

                // 计算总数
                pageList.PageCount = query.Count();
                
                // 分页和排序
                pageList.ListDate = query
                    .OrderByDescending(m => m.Id)
                    .Skip((queryDto.Page - 1) * queryDto.Limit)
                    .Take(queryDto.Limit)
                    .ToList();

                // 计算总页数
                pageList.PageIndex = Convert.ToInt32(Math.Ceiling(pageList.PageCount * 1.0 / queryDto.Limit));

                return pageList;
            }
            catch (Exception ex)
            {
                throw new Exception($"查询客户订单列表失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 根据ID获取客户订单详情
        /// </summary>
        /// <param name="id">订单ID</param>
        /// <returns>订单详情</returns>
        public async Task<CustomerOrderModel> GetCustomerOrderById(int id)
        {
            try
            {
                var order = await _customerOrderModelBrs.FirstOrDefaultAsync(x => x.Id == id);
                if (order == null)
                {
                    throw new ArgumentException($"订单ID {id} 不存在");
                }
                return order;
            }
            catch (Exception ex)
            {
                throw new Exception($"获取客户订单详情失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 更新客户订单
        /// </summary>
        /// <param name="customerOrderDto">客户订单信息</param>
        /// <returns>更新结果</returns>
        public async Task<bool> UpdateCustomerOrder(CustomerOrderDto customerOrderDto)
        {
            try
            {
                // 验证订单是否存在
                var existingOrder = await _customerOrderModelBrs.FirstOrDefaultAsync(x => x.Id == customerOrderDto.Id);
                if (existingOrder == null)
                {
                    throw new ArgumentException($"订单ID {customerOrderDto.Id} 不存在");
                }

                // 验证必需字段
                if (string.IsNullOrEmpty(customerOrderDto.ProductCode))
                    throw new ArgumentException("产品编号不能为空");
                if (string.IsNullOrEmpty(customerOrderDto.ProductName))
                    throw new ArgumentException("产品名称不能为空");
                if (string.IsNullOrEmpty(customerOrderDto.CustomerName))
                    throw new ArgumentException("客户名称不能为空");
                if (string.IsNullOrEmpty(customerOrderDto.Unit))
                    throw new ArgumentException("单位不能为空");

                // 更新订单信息（注意：订单编码不允许修改）
                existingOrder.ProductCode = customerOrderDto.ProductCode ?? "";
                existingOrder.ProductName = customerOrderDto.ProductName ?? "";
                existingOrder.ProductSpec = customerOrderDto.ProductSpec ?? "";
                existingOrder.CustomerCode = customerOrderDto.CustomerCode ?? "";
                existingOrder.CustomerName = customerOrderDto.CustomerName ?? "";
                existingOrder.OrderDate = customerOrderDto.OrderDate;
                existingOrder.DeliveryDate = customerOrderDto.DeliveryDate;
                existingOrder.OrderQuantity = customerOrderDto.OrderQuantity;
                existingOrder.Unit = customerOrderDto.Unit ?? "";
                existingOrder.SpecificationModel = customerOrderDto.SpecModel ?? "";
                existingOrder.QualityRequirement = customerOrderDto.QualityRequirements ?? "";
                existingOrder.OrderStatus = customerOrderDto.OrderStatus;

                // 保存更改
                await _customerOrderModelBrs.UpdateAsync(existingOrder, autoSave: true);
                
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception($"更新客户订单失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 批量删除客户订单
        /// </summary>
        /// <param name="ids">订单ID数组</param>
        /// <returns>删除结果</returns>
        public async Task<bool> DeleteCustomerOrders(int[] ids)
        {
            try
            {
                if (ids == null || ids.Length == 0)
                {
                    throw new ArgumentException("删除的订单ID不能为空");
                }

                // 验证所有订单是否存在
                var orders = await _customerOrderModelBrs.GetListAsync(x => ids.Contains(x.Id));
                if (orders.Count != ids.Length)
                {
                    var existingIds = orders.Select(x => x.Id).ToArray();
                    var missingIds = ids.Except(existingIds).ToArray();
                    throw new ArgumentException($"以下订单ID不存在: {string.Join(", ", missingIds)}");
                }

                // 检查订单状态，防止删除正在处理中的订单
                var processingOrders = orders.Where(x => x.OrderStatus > 1).ToList();
                if (processingOrders.Any())
                {
                    var processingOrderNumbers = processingOrders.Select(x => x.OrderNumber).ToArray();
                    throw new InvalidOperationException($"以下订单正在处理中，无法删除: {string.Join(", ", processingOrderNumbers)}");
                }

                // 执行批量删除
                await _customerOrderModelBrs.DeleteManyAsync(orders, autoSave: true);
                
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception($"批量删除客户订单失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 分页查询物料产品列表
        /// </summary>
        /// <param name="materielCode">物料编码</param>
        /// <param name="materielName">物料名称</param>
        /// <param name="page">当前页</param>
        /// <param name="limit">每页数量</param>
        /// <returns>分页物料列表</returns>
        public async Task<APIPaging<MaterialproductModel>> GetMaterialProductList(string? materielCode, string? materielName, int page = 1, int limit = 10)
        {
            try
            {
                var pageList = new APIPaging<MaterialproductModel>();
                var query = await _materialproductModelBrs.GetQueryableAsync();

                // 条件筛选
                query = query.WhereIf(!string.IsNullOrEmpty(materielCode), 
                    m => m.MaterielCode.Contains(materielCode));
                
                query = query.WhereIf(!string.IsNullOrEmpty(materielName), 
                    m => m.MaterielName.Contains(materielName));



                // 计算总数
                pageList.PageCount = query.Count();
                
                // 分页和排序
                pageList.ListDate = query
                    .OrderByDescending(m => m.Id)
                    .Skip((page - 1) * limit)
                    .Take(limit)
                    .ToList();

                // 计算总页数
                pageList.PageIndex = Convert.ToInt32(Math.Ceiling(pageList.PageCount * 1.0 / limit));

                return pageList;
            }
            catch (Exception ex)
            {
                throw new Exception($"查询物料产品列表失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 根据订单ID获取物料需求列表
        /// </summary>
        /// <param name="customerOrderId">客户订单ID</param>
        /// <returns>物料需求列表</returns>
        public async Task<List<MaterialRequirementDto>> GetMaterialRequirementsByOrderId(int customerOrderId)
        {
            try
            {
                var materialRequirements = await _materialRequirementRepository.GetListAsync(
                    x => x.CustomerOrderId == customerOrderId && !x.IsDeleted);

                // 按照sortOrder排序
                var sortedRequirements = materialRequirements.OrderBy(x => x.SortOrder).ToList();

                // 转换为DTO
                var result = sortedRequirements.Select(item => new MaterialRequirementDto
                {
                    Id = item.Id,
                    CustomerOrderId = item.CustomerOrderId,
                    ParentId = item.ParentId,
                    Level = item.Level,
                    IsLevelTitle = item.IsLevelTitle,
                    LevelTitle = item.LevelTitle,
                    MaterialCode = item.MaterialCode,
                    MaterialName = item.MaterialName,
                    Specifications = item.Specifications,
                    RequiredQuantity = item.RequiredQuantity,
                    InventoryQuantity = item.InventoryQuantity,
                    Unit = item.Unit,
                    Remark = item.Remark,
                    SortOrder = item.SortOrder,
                    CreateTime = item.CreateTime,
                    CreateUser = item.CreateUser,
                    UpdateTime = item.UpdateTime,
                    UpdateUser = item.UpdateUser,
                    IsDeleted = item.IsDeleted
                }).ToList();

                return result;
            }
            catch (Exception ex)
            {
                throw new Exception($"获取物料需求数据失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 带事务的更新客户订单和物料需求
        /// </summary>
        /// <param name="customerOrderDto">客户订单信息</param>
        /// <param name="materialRequirements">物料需求列表</param>
        /// <returns>更新结果</returns>
        [UnitOfWork]
        public async Task<bool> UpdateCustomerOrderWithMaterialRequirements(CustomerOrderDto customerOrderDto, List<MaterialRequirementDto> materialRequirements)
        {
            try
            {
                // 验证订单是否存在
                var existingOrder = await _customerOrderModelBrs.FirstOrDefaultAsync(x => x.Id == customerOrderDto.Id);
                if (existingOrder == null)
                {
                    throw new ArgumentException($"订单ID {customerOrderDto.Id} 不存在");
                }

                // 验证必需字段
                if (string.IsNullOrEmpty(customerOrderDto.ProductCode))
                    throw new ArgumentException("产品编号不能为空");
                if (string.IsNullOrEmpty(customerOrderDto.ProductName))
                    throw new ArgumentException("产品名称不能为空");
                if (string.IsNullOrEmpty(customerOrderDto.CustomerName))
                    throw new ArgumentException("客户名称不能为空");
                if (string.IsNullOrEmpty(customerOrderDto.Unit))
                    throw new ArgumentException("单位不能为空");

                // 更新订单信息
                existingOrder.ProductCode = customerOrderDto.ProductCode ?? "";
                existingOrder.ProductName = customerOrderDto.ProductName ?? "";
                existingOrder.ProductSpec = customerOrderDto.ProductSpec ?? "";
                existingOrder.CustomerCode = customerOrderDto.CustomerCode ?? "";
                existingOrder.CustomerName = customerOrderDto.CustomerName ?? "";
                existingOrder.OrderDate = customerOrderDto.OrderDate;
                existingOrder.DeliveryDate = customerOrderDto.DeliveryDate;
                existingOrder.OrderQuantity = customerOrderDto.OrderQuantity;
                existingOrder.Unit = customerOrderDto.Unit ?? "";
                existingOrder.SpecificationModel = customerOrderDto.SpecModel ?? "";
                existingOrder.QualityRequirement = customerOrderDto.QualityRequirements ?? "";
                existingOrder.OrderStatus = customerOrderDto.OrderStatus;

                // 更新订单
                await _customerOrderModelBrs.UpdateAsync(existingOrder, autoSave: false);

                // 删除原有的物料需求
                var existingRequirements = await _materialRequirementRepository.GetListAsync(
                    x => x.CustomerOrderId == customerOrderDto.Id);
                if (existingRequirements.Any())
                {
                    await _materialRequirementRepository.DeleteManyAsync(existingRequirements, autoSave: false);
                }

                // 批量插入新的物料需求
                if (materialRequirements != null && materialRequirements.Any())
                {
                    var now = DateTime.Now;
                    
                    var newRequirements = materialRequirements.Select(dto => new MaterialRequirementModel
                    {
                        CustomerOrderId = customerOrderDto.Id,
                        ParentId = dto.ParentId,
                        Level = dto.Level,
                        IsLevelTitle = dto.IsLevelTitle,
                        LevelTitle = dto.LevelTitle ?? "",
                        MaterialCode = dto.MaterialCode ?? "",
                        MaterialName = dto.MaterialName ?? "",
                        Specifications = dto.Specifications ?? "",
                        RequiredQuantity = dto.RequiredQuantity,
                        InventoryQuantity = dto.InventoryQuantity,
                        Unit = dto.Unit ?? "",
                        Remark = dto.Remark ?? "",
                        SortOrder = dto.SortOrder,
                        CreateUser = dto.CreateUser ?? "system",
                        CreateTime = now,
                        UpdateUser = dto.CreateUser ?? "system",
                        UpdateTime = now,
                        IsDeleted = false
                    }).ToList();

                    await _materialRequirementRepository.InsertManyAsync(newRequirements, autoSave: false);
                }

                // 统一提交事务
                await UnitOfWorkManager.Current.SaveChangesAsync();
                
                return true;
            }
            catch (Exception ex)
            {
                throw new Exception($"更新客户订单和物料需求失败: {ex.Message}", ex);
            }
        }
    }
}
